import type { TimeRange } from '@/components/predetermine-datetime-selector/utils.type'

export function formatTime(src: string | null | undefined, format: string): string {
  if (src == null) return ''
  const srcArr = src.split(':')
  const srcMap: { [key: string]: string } = {
    HH: srcArr[0] ?? '',
    mm: srcArr[1] ?? '',
    ss: srcArr[2] ?? ''
  }
  const srcMapKeys = Object.keys(srcMap)
  srcMapKeys.forEach((srcMapKey) => {
    format = format.replaceAll(srcMapKey, srcMap[srcMapKey])
  })
  return format
}

export function formatDateTime(timeStr: string, format = 'yyyy-MM-dd HH:mm') {
  return new TimeOperations().init(timeStr).formatDate(format)
}

export class TimeOperations {
  private date: Date

  constructor() {
    this.date = new Date()
  }
  setCoreDate(date: Date) {
    this.date = date
    return this
  }
  public setYMD(
    year?: number | string | undefined | null,
    month?: number | string | undefined | null,
    day?: number | string | undefined | null
  ) {
    year = parseInt((year ?? '') + '')
    month = parseInt((month ?? '') + '')
    day = parseInt((day ?? '') + '')
    this.date.setFullYear(isNaN(year) ? this.date.getFullYear() : year)
    this.date.setMonth(isNaN(month) ? this.date.getMonth() + 1 : month - 1)
    this.date.setDate(isNaN(day) ? this.date.getDate() : day)
    return this
  }
  public copyInstance(): TimeOperations {
    return new TimeOperations().setCoreDate(new Date(this.date.getTime()))
  }
  public setHMS(
    hour?: number | string | undefined | null,
    minute?: number | string | undefined | null,
    second?: number | string | undefined | null
  ) {
    hour = parseInt((hour ?? '') + '')
    minute = parseInt((minute ?? '') + '')
    second = parseInt((second ?? '') + '')
    this.date.setHours(isNaN(hour) ? this.date.getHours() : hour)
    this.date.setMinutes(isNaN(minute) ? this.date.getMinutes() : minute)
    this.date.setSeconds(isNaN(second) ? this.date.getSeconds() : second)
    return this
  }
  public init(dateFormat: string) {
    // 固定格式yyyy-MM-dd HH:mm:ss
    const dateArr = dateFormat.trim().split(/\s+/)
    this.update(dateArr[0], dateArr[1])
    return this
  }
  public update(
    ymd?: string | { yyyy?: number; mm?: number; dd?: number },
    hms?: string | { hh?: number; mm?: number; ss?: number }
  ) {
    // 解析ymd
    if (ymd != null) {
      if (typeof ymd === 'string') {
        // ymd应该是固定格式的yyyy-mm-dd或者是mm-dd
        const ymdArr = ymd.split('-')
        const yyyy = ymdArr.shift()
        const mm = ymdArr.shift()
        const dd = ymdArr.shift()
        this.setYMD(yyyy, mm, dd)
      } else if (typeof ymd === 'object') {
        this.setYMD(ymd.yyyy, ymd.mm, ymd.dd)
      }
    }
    // 解析hms
    if (hms != null) {
      if (typeof hms === 'string') {
        // hms应该是固定格式的HH:mm:ss
        const hmsArr = hms.split(':')
        const hh = hmsArr.shift()
        const mm = hmsArr.shift()
        const ss = hmsArr.shift()
        this.setHMS(hh, mm, ss)
      } else if (typeof hms === 'object') {
        this.setYMD(hms.hh, hms.mm, hms.ss)
      }
    }
    return this
  }

  addMinutes(minutes: number) {
    // 会累加 70 -> 1小时10分钟
    this.date.setMinutes(this.date.getMinutes() + minutes)
    return this
  }
  addDay(dayNum: number) {
    this.date.setDate(this.date.getDate() + dayNum)
    return this
  }
  getCoreDate() {
    return this.date
  }
  ymdEquals(ymd: string, formatTemplate: string) {
    return this.formatDate(formatTemplate) === ymd
  }
  hmsLt(hms: string | { hh: number; mm: number; ss: number }) {
    const hmsObj = { hh: 0, mm: 0, ss: 0 }
    if (typeof hms === 'string') {
      const hmsArr = hms.split(':')
      hmsObj.hh = parseInt(hmsArr.shift() ?? '0')
      hmsObj.mm = parseInt(hmsArr.shift() ?? '0')
      hmsObj.ss = parseInt(hmsArr.shift() ?? '0')
    } else if (typeof hms === 'object') {
      hmsObj.hh = hms.hh
      hmsObj.mm = hms.mm
      hmsObj.ss = hms.ss
    } else {
      return false
    }
    if (this.date.getHours() !== hmsObj.hh) {
      return this.date.getHours() < hmsObj.hh
    }
    if (this.date.getMinutes() !== hmsObj.mm) {
      return this.date.getMinutes() < hmsObj.mm
    }
    if (this.date.getSeconds() !== hmsObj.ss) {
      return this.date.getSeconds() < hmsObj.ss
    }
    return false
  }
  formatDate(formatString = 'yyyy-MM-dd HH:mm:ss'): string {
    formatString = formatString.replaceAll('yyyy', this.date.getFullYear() + '')
    formatString = formatString.replaceAll('MM', ('00' + (this.date.getMonth() + 1)).slice(-2))
    formatString = formatString.replaceAll('dd', ('00' + this.date.getDate()).slice(-2))
    formatString = formatString.replaceAll('HH', ('00' + this.date.getHours()).slice(-2))
    formatString = formatString.replaceAll('mm', ('00' + this.date.getMinutes()).slice(-2))
    formatString = formatString.replaceAll('ss', this.date.getSeconds() + '')
    return formatString
  }
  getDayOfWeek(): string {
    const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
    return days[this.date.getDay()]
  }
  public getTimestamp() {
    return this.date.getTime()
  }
}

interface ShopBusinessTime {
  beginTime: string
  endTime: string
}

export const filterTime = function (timeRanges: TimeRange[], currentTime?: string): TimeRange[] {
  if (currentTime == null) {
    const now = new Date()
    currentTime = `${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`
  }
  // time -> number
  const timeToNumber = (time: string) => {
    if (time == null || time.length === 0 || !time.includes(':')) return 0
    const timeArr = time.split(':')
    return parseInt(timeArr[0]) * 60 + parseInt(timeArr[1])
  }
  const current = timeToNumber(currentTime)
  const result: TimeRange[] = []

  // 遍历每一个时间段
  for (let i = 0; i < timeRanges.length; i++) {
    const interval = timeRanges[i]

    const begin = timeToNumber(interval.startTime)
    const end = timeToNumber(interval.endTime)

    // 如果当前时间在时间段内，修改开始时间为当前时间，然后加入列表
    if (current >= begin && current <= end) {
      interval.startTime = currentTime
      result.push(interval)
    }
    // 如果当前时间小于该时间段，直接添加该时间段到结果，并退出循环
    else if (current < begin) {
      result.push(interval)
    }
  }
  return result
}
/**
 * 为对象中的Date对象转为指定格式的字符串对象
 * @param obj
 * @param dateFormat
 * @returns
 */
export function formatDateForObjectWithDates(obj: any, dateFormat: string = 'yyyy-MM-dd HH:mm:ss'): any {
  if (obj instanceof Date) {
    // 如果是 Date 类型，将其转换为指定格式的字符串
    const formattedDate = formatDate(obj, dateFormat)
    return formattedDate
  } else if (typeof obj === 'object') {
    // 如果是对象，则递归处理每个属性
    for (const key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) {
        obj[key] = formatDateForObjectWithDates(obj[key], dateFormat)
      }
    }
  }
  // 返回处理后的对象
  return obj
}

function formatDate(date: Date, format: string): string {
  if (date == null) return format
  const year = date.getFullYear()
  const month = (date.getMonth() + 1).toString().padStart(2, '0')
  const day = date.getDate().toString().padStart(2, '0')
  const hours = date.getHours().toString().padStart(2, '0')
  const minutes = date.getMinutes().toString().padStart(2, '0')
  const seconds = date.getSeconds().toString().padStart(2, '0')

  const formattedDate = format
    .replace('yyyy', year.toString())
    .replace('MM', month)
    .replace('dd', day)
    .replace('HH', hours)
    .replace('mm', minutes)
    .replace('ss', seconds)

  return formattedDate
}
